package
{
	import flash.net.SharedObject;
	import flash.utils.ByteArray;
	
	/*
	Flash Storage Settings:
	http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager07.html
	*/
	
	public class Disk
	{
		private static const MAGIC:String = "M1DISK" /* Unique ID for this app. */
		private static const BLOCKSIZE:uint = 512 /* Block size of all disks. */
		public static var SIZE:uint = 90*1024; /* Size of the disk, in bytes. Note that it may grow if the user permits. */
		private static var SOB:SharedObject; /* TODO: as whole image? blocks? "clusters?" */
		
		/* TODO: cache image built from Boot ROMs into a local disk image, for faster loading. */
		/* Cache details: right now, one-way flow down from server. */
		
		/* Warn user if creating fresh disk, or local store is non-writable. */
		/* TODO: invite user to remove 100KB limit. */
		public static function InitDisk():void {
			SOB = SharedObject.getLocal(MAGIC);
			/* !!!! */
			if (SOB.size == 0) Format();
			//Format();
		}
		
		/* Returns the free space remaining on the disk. This may increase if the disk grows. */
		public static function getDiskFree():uint {
			return SIZE - SOB.size;
		}
		
		/* Format a new Disk, wiping any previous contents. */
		public static function Format():void {
			debug("Formatting!");
			SOB.clear();
			SOB.data.formatstring = MAGIC;
			/* test */
			SOB.data.bytes = new ByteArray();
			
			for (var i:uint = 0; i<(SIZE-1); i++) SOB.data.bytes[i] = 1;
			SOB.data.bytes = RAM.bytes; /* true, this is cheap */
			
			/* test */
			SOB.flush();
		}
		
		/* Copy blocks from disk (starting at sblock) to buffer (starting at rambuf.) */
		public static function ReadBlocks(rambuf:uint, sblock:uint, bcount:uint):void {
			debug("Attempting Read...");
			debug("= "+bcount+" Blocks, starting from No."+sblock+" into RAM at "+rambuf);
			SOB.data.bytes.position = BLOCKSIZE*sblock;
			SOB.data.bytes.readBytes(RAM.bytes, rambuf, BLOCKSIZE*bcount);
			debug("Read "+bcount+" Blocks, starting from No."+sblock+" into RAM at "+rambuf);
		}
		
		/* Copy blocks from buffer (starting at rambuf) to disk (starting at sblock.) */
		public static function WriteBlocks(rambuf:uint, sblock:uint, bcount:uint):void {
			debug("Attempting Write...");
			debug("= "+bcount+" Blocks, starting from No."+sblock+" from RAM at "+rambuf);
			RAM.bytes.position = rambuf;
			RAM.bytes.readBytes(SOB.data.bytes, sblock*BLOCKSIZE, BLOCKSIZE*bcount);
			debug("Wrote "+bcount+" Blocks, starting from No."+sblock+" from RAM at "+rambuf);
		}
		
		/* Try to sync the Disk with the local store. */
		public static function Sync():void {
			debug("Starting Sync");
			SOB.flush();
		}
				
        private static function debug(msg:String):void {
        	m1.debug.print("DISK: " + msg);
        }
	}
}